﻿#include "StdAfx.h"
#include "BigDrawing2MoAnimation.h"
#include "HBaseView.h"
#include "HBhvTimeline.h"
#include "HBhvAnimation.h"
#include "HBhvBehaviorManager.h"
#include "HUtilityGeomHandle.h"
#include "../ModelTool/HModelLayerModel.h"
#include "../ModelTool/HModelLayerView.h"
#include "../ModelTool/HMySelectionSet.h"
#include "../ModelObj/Wire.h"
#include "../ModelObj/WireDisplayObj.h"
#include "../ModelObj/TriangleDisplayObj.h"
#include "../ModelObj/SchematicBus.h"
#include "../ModelObj/SchematicBusEntry.h"
#include "../ModelObj/MoSchematicConnector.h"
#include "../ModelObj/ImportConfigData.h"
#include "XmlRWUtils.h"
#include "StringUtils.h"

CBigDrawing2MoAnimation::CBigDrawing2MoAnimation(void)
{
	m_bPostData=false;
}


CBigDrawing2MoAnimation::~CBigDrawing2MoAnimation(void)
{
}


void CBigDrawing2MoAnimation::OutputDynamicComponentInfo( HBaseView* pHView )
{
	m_VarName2RefMap.clear();

	HModelLayerModel* pHmodel = (HModelLayerModel*)pHView->GetModel();
	CSystem* pBigDrawing = pHmodel->GetBigDrawing();
	CLayer *pLayer = GetAnimationFlowLayer(pHView);
	if ( !pLayer )
	{
		return;
	}
	int id=0;

	TiXmlDeclaration Declaration( "1.0","", "" );  
	TiXmlDocument xmlDoc( "DynamicComponentInfo.xml" );   
	xmlDoc.InsertEndChild( Declaration );   
	TiXmlElement elmRoot( "DynamicComponentVariableConfig" );

	//【Global】
	TiXmlElement global("Global");
	
	//Solar "光照强度"
	TiXmlElement soloar("Solar");
	soloar.SetAttribute("VarName","Solar");
	soloar.SetAttribute("ref",++id);
	global.InsertEndChild(soloar);
	AddVariableInfo(_T("Solar"),id);

	//VBusAdj  "全调节母线电压"
	TiXmlElement vbusadj("VBusAdj");
	vbusadj.SetAttribute("VarName","V_Bus_Adj");
	vbusadj.SetAttribute("ref",++id);
	global.InsertEndChild(vbusadj);
	AddVariableInfo(_T("V_Bus_Adj"),id);

	//VBusNotAdj  "不调节母线电压"
	TiXmlElement vbusnotadj("VBusNotAdj");
	vbusnotadj.SetAttribute("VarName","V_Bus_NotAdj");
	vbusnotadj.SetAttribute("ref",++id);
	global.InsertEndChild(vbusnotadj);
	AddVariableInfo(_T("V_Bus_NotAdj"),id);

	//IBusAdj  "全调节母线电流"
	TiXmlElement ibusadj("IBusAdj");
	ibusadj.SetAttribute("VarName","I_Bus_Adj");
	ibusadj.SetAttribute("ref",++id);
	global.InsertEndChild(ibusadj);
	AddVariableInfo(_T("I_Bus_Adj"),id);

	//IBusNotAdj "不调节母线电流"
	TiXmlElement ibusnotadj("IBusNotAdj");
	ibusnotadj.SetAttribute("VarName","I_Bus_NotAdj");
	ibusnotadj.SetAttribute("ref",++id);
	global.InsertEndChild(ibusnotadj);
	AddVariableInfo(_T("I_Bus_NotAdj"),id);

	//PSolar "太阳能电池阵输出功率"
	TiXmlElement psoloar("PSolar");
	psoloar.SetAttribute("VarName","P_Solar");
	psoloar.SetAttribute("ref",++id);
	global.InsertEndChild(psoloar);
	AddVariableInfo(_T("P_Solar"),id);

	//PLoad "总负载功率"
	TiXmlElement pload("PLoad");
	pload.SetAttribute("VarName","P_Load");
	pload.SetAttribute("ref",++id);
	global.InsertEndChild(pload);
	AddVariableInfo(_T("P_Load"),id);

	//PLoadAdj "全调节负载总功率"
	TiXmlElement PLoadAdj("PLoadAdj");
	PLoadAdj.SetAttribute("VarName","P_Load_Adj");
	PLoadAdj.SetAttribute("ref",++id);
	global.InsertEndChild(PLoadAdj);
	AddVariableInfo(_T("P_Load_Adj"),id);

	//PLoadNotAdj "不调节负载总功率"
	TiXmlElement PLoadNotAdj("PLoadNotAdj");
	PLoadNotAdj.SetAttribute("VarName","P_Load_NotAdj");
	PLoadNotAdj.SetAttribute("ref",++id);
	global.InsertEndChild(PLoadNotAdj);
	AddVariableInfo(_T("P_Load_NotAdj"),id);

	//VBattery  "电池组电压"
	TiXmlElement VBattery("VBattery");
	VBattery.SetAttribute("VarName","V_Battery");
	VBattery.SetAttribute("ref",++id);
	global.InsertEndChild(VBattery);
	AddVariableInfo(_T("V_Battery"),id);

	//DOD  "蓄电池组放电深度"
	TiXmlElement dod("DOD");
	dod.SetAttribute("VarName","DOD");
	dod.SetAttribute("ref",++id);
	global.InsertEndChild(dod);
	AddVariableInfo(_T("DOD"),id);

	//SOC  "蓄电池组荷电状态"
	TiXmlElement soc("SOC");
	soc.SetAttribute("VarName","SOC");
	soc.SetAttribute("ref",++id);
	global.InsertEndChild(soc);
	AddVariableInfo(_T("SOC"),id);

	//PBatteryIn "蓄电池组总的充电功率"
	TiXmlElement PBatteryIn("PBatteryIn");
	PBatteryIn.SetAttribute("VarName","P_BatteryIn");
	PBatteryIn.SetAttribute("ref",++id);
	global.InsertEndChild(PBatteryIn);
	AddVariableInfo(_T("P_BatteryIn"),id);

	//PBatteryOut "蓄电池组总的放电功率"
	TiXmlElement PBatteryOut("PBatteryOut");
	PBatteryOut.SetAttribute("VarName","P_BatteryOut");
	PBatteryOut.SetAttribute("ref",++id);
	global.InsertEndChild(PBatteryOut);
	AddVariableInfo(_T("P_BatteryOut"),id);

	//Time
	TiXmlElement time("Time");
	time.SetAttribute("VarName","time");
	time.SetAttribute("ref",++id);
	global.InsertEndChild(time);
	AddVariableInfo(_T("time"),id);

	elmRoot.InsertEndChild(global);

	//【System】
	TiXmlElement system("System");

	const std::list<CSubSystem *> listSubSystem = pBigDrawing->GetSubSystemList();
	std::list<CSubSystem *>::const_iterator it_sub_sys = listSubSystem.begin();

	GetPositiveShowedWireDisObj(pBigDrawing,pLayer); //正线数据准备

	//遍历分系统
	for( ; it_sub_sys!=listSubSystem.end(); it_sub_sys++ )
	{
		CSubSystem *pSubSys = *it_sub_sys;
		
		if( !IsPowerSupplySystem(pSubSys) )
		{
			TiXmlElement subsystem("SubSystem");
			CString strSubSysName = pSubSys->GetName();
			std::string stdSubSysName;
			StringUtils::CStringToStdstring(strSubSysName,stdSubSysName);
			std::string utf8_subSysName = StringUtils::GBKToUTF8(stdSubSysName);
			subsystem.SetAttribute("Name",utf8_subSysName.c_str());
			

			const std::list<CDevice*> listDevice = pSubSys->GetDeviceList();
			std::list<CDevice*>::const_iterator it_device = listDevice.begin();

			//遍历设备
			for( ; it_device!= listDevice.end(); it_device++ )
			{
				CDevice *pDevice = *it_device;
				CDisplayObj *pDeviceDis = pDevice->GetDisplayObjByLayerID(pLayer->GetId());

				if( pDeviceDis== NULL)
					continue;

				TiXmlElement device("Device");

				//NO
				CString strDeviceNo = pDevice->GetNo();
				std::string stdstrDeviceNo;
				StringUtils::CStringToStdstring(strDeviceNo,stdstrDeviceNo);
				device.SetAttribute("NO",stdstrDeviceNo.c_str());

				//Name
				CString strDeviceName = pDevice->GetName();
				std::string stdstrDeviceName;
				StringUtils::CStringToStdstring(strDeviceName,stdstrDeviceName);
				std::string utf8_deviceName = StringUtils::GBKToUTF8(stdstrDeviceName);
				device.SetAttribute("Name",utf8_deviceName.c_str());

				//ref
				device.SetAttribute("ref",++id);

				//VarName
				CString strPowerLoss = pDevice->GetNo();
				strPowerLoss+=_T(".PowerLoss");
				strPowerLoss.Replace(_T("-"),_T("_"));

				AddVariableInfo(strPowerLoss,id);

				std::string stdstrPowerLoss;
				StringUtils::CStringToStdstring(strPowerLoss,stdstrPowerLoss);
				device.SetAttribute("VarName",stdstrPowerLoss.c_str());


				if( pDevice )
				{
					
					std::list<CWireDisplayObj*> lstWires;
					map<CDevice*,list<CWireDisplayObj*>>::iterator it_Dev2PositiveWires = m_mapDev2PositiveWires.find(pDevice);
					if(it_Dev2PositiveWires!= m_mapDev2PositiveWires.end())
						lstWires = it_Dev2PositiveWires->second;

					list<CWireDisplayObj*>::iterator iter_wireDis = lstWires.begin();
					for (; iter_wireDis!= lstWires.end(); iter_wireDis++)
					{
						CWireDisplayObj* pWireDis=  *iter_wireDis;
						CWire* pWire = (CWire*)pWireDis->GetEntityObj();
						
						if (IsMoMergeLayer())
						{
							CPin* pStPin = pWire->GetStartPin();
							CPin* pEndPin = pWire->GetEndPin();
							if( pStPin->GetParentEntity()->GetParentEntity() == pDevice )
							{
								TiXmlElement current("I");
								CString strCurrentName = GetPinCurrentVarName(pStPin);

								current.SetAttribute("ref",++id);
								AddVariableInfo(strCurrentName,id);

								std::string stdstrCurrentName;
								StringUtils::CStringToStdstring(strCurrentName,stdstrCurrentName);
								current.SetAttribute("VarName",stdstrCurrentName.c_str());

								device.InsertEndChild(current);
							}
							if( pEndPin->GetParentEntity()->GetParentEntity() == pDevice )
							{
								TiXmlElement current("I");
								CString strCurrentName = GetPinCurrentVarName(pEndPin);

								current.SetAttribute("ref",++id);
								AddVariableInfo(strCurrentName,id);

								std::string stdstrCurrentName;
								StringUtils::CStringToStdstring(strCurrentName,stdstrCurrentName);
								current.SetAttribute("VarName",stdstrCurrentName.c_str());

								device.InsertEndChild(current);
							}

							continue;
						}

						vector<CPin* > vecStPin,vecEndPin;
						GetWireDisObjMergerdPins(pWireDis,vecStPin,vecEndPin);
						for (int nIndex= 0; nIndex!= vecStPin.size() ; nIndex++)
						{			
							CPin* pPin = vecStPin[nIndex];
							if( pPin->GetParentEntity()->GetParentEntity() == pDevice )
							{
								TiXmlElement current("I");
								CString strCurrentName = GetPinCurrentVarName(pPin);

								current.SetAttribute("ref",++id);
								AddVariableInfo(strCurrentName,id);

								std::string stdstrCurrentName;
								StringUtils::CStringToStdstring(strCurrentName,stdstrCurrentName);
								current.SetAttribute("VarName",stdstrCurrentName.c_str());

								device.InsertEndChild(current);

							}

						}
						for (int nIndex= 0; nIndex!= vecEndPin.size() ; nIndex++)
						{
							CPin* pPin = vecEndPin[nIndex];
							if( pPin->GetParentEntity()->GetParentEntity() == pDevice )
							{
								TiXmlElement current("I");
								CString strCurrentName = GetPinCurrentVarName(pPin);

								current.SetAttribute("ref",++id);
								AddVariableInfo(strCurrentName,id);

								std::string stdstrCurrentName;
								StringUtils::CStringToStdstring(strCurrentName,stdstrCurrentName);
								current.SetAttribute("VarName",stdstrCurrentName.c_str());

								device.InsertEndChild(current);
							}
						}
					}

				}
				
				subsystem.InsertEndChild(device);

			}

			system.InsertEndChild(subsystem);
		}
	}

	elmRoot.InsertEndChild(system);
	xmlDoc.InsertEndChild(elmRoot);
	CString strPath = CModelObjOption::GetInstallDir();
	std::string stdStrPath;
	StringUtils::CStringToStdstring(strPath,stdStrPath);
	string strSavePath = stdStrPath + "\\Temp\\DynamicComponentInfo.xml";
	xmlDoc.SaveFile(strSavePath);  


}


CString CBigDrawing2MoAnimation::GetDevicePowerLossVarName( CDevice* pDev )
{
	CString sDevNo = pDev->GetNo();
	sDevNo.Replace(_T("-"),_T("_"));
	sDevNo.Replace(_T(" "),_T(""));

	sDevNo+=_T(".PowerLoss");

	return sDevNo;
}


CString CBigDrawing2MoAnimation:: GetActiveLayerMoParams(HBaseView* pHView)
{
	CLayer* pLayer = GetAnimationFlowLayer(pHView);
	if ( !pLayer )
	{
		return _T("");
	}

	if( !GetPowerFlowParams().IsEmpty() )
		return GetPowerFlowParams();


	HModelLayerModel* pHmodel = (HModelLayerModel*)pHView->GetModel();
	CSystem* pBigDrawing = pHmodel->GetBigDrawing();
	list<CDevice*> lstDevs;
	pBigDrawing->GetAllDevices(lstDevs);

	vector<CString> vecParams;
	for (list<CDevice*>::iterator iter = lstDevs.begin();iter!=lstDevs.end();iter++)
	{
		CDevice* pDev = *iter; //无需判断显示对象是否存在，一并获取，再在各层中判断处理;
		if (pDev->IsProxyDevice())
		{
			continue;
		}
		CString sDevPower = GetDevicePowerLossVarName(pDev);
		vecParams.push_back(sDevPower);
	}

	list<CWireDisplayObj*>::iterator iter_wireDis = m_lstPositiveWireDis.begin();
	for (; iter_wireDis!= m_lstPositiveWireDis.end(); iter_wireDis++)
	{
		CWireDisplayObj* pWireDis=  *iter_wireDis;
		CWire* pWire = (CWire*) pWireDis->GetEntityObj();
		CPin* pSt = pWire->GetStartPin();
		CPin* pEnd = pWire->GetEndPin();

		if (IsMoMergeLayer())
		{
			vecParams.push_back(GetPinCurrentVarName(pSt));
			vecParams.push_back(GetPinVoltageVarName(pSt));
			vecParams.push_back(GetPinCurrentVarName(pEnd));
			vecParams.push_back(GetPinVoltageVarName(pEnd));
			
			continue;
		}


		vector<CPin* > vecStPin,vecEndPin;
		GetWireDisObjMergerdPins(pWireDis,vecStPin,vecEndPin);
		for (int nIndex= 0; nIndex!= vecStPin.size() ; nIndex++)
		{
			CPin* pPin = vecStPin[nIndex];
			vecParams.push_back(GetPinCurrentVarName(pPin));
			vecParams.push_back(GetPinVoltageVarName(pPin));
		}
		for (int nIndex= 0; nIndex!= vecEndPin.size() ; nIndex++)
		{
			CPin* pPin = vecEndPin[nIndex];
			vecParams.push_back(GetPinCurrentVarName(pPin));
			vecParams.push_back(GetPinVoltageVarName(pPin));
		}
	}

	CString sRetParamsInfo;
	for ( int nIndex=0; nIndex!= vecParams.size() ; nIndex++)
	{
		sRetParamsInfo = sRetParamsInfo+vecParams[nIndex];
		sRetParamsInfo = sRetParamsInfo + _T(" double 0.0");
		if (nIndex != vecParams.size()-1 )
		{
			sRetParamsInfo = sRetParamsInfo+_T(" ");
		} 
	}

	SetPowerFlowParams(sRetParamsInfo);

	return sRetParamsInfo;
}

bool CBigDrawing2MoAnimation::GetWireDisObjVoltage_BelongProxyDeviceOrSepConn(CWireDisplayObj* pWireDisObj,double &dSt,double &dEnd)
{
	dSt=dEnd=0;
	CWire* pWire = (CWire*)pWireDisObj->GetEntityObj();
	CPin* pPin1 = NULL;
	CPin* pPin2 = NULL;
	CWire* pAssoWire = NULL ;
	if ( !m_linkWireTool.GetAssoLinkWire(pWire,pAssoWire,pPin1,pPin2) || pAssoWire == NULL)
	{
		GetWireDisObjVoltage(pWireDisObj,dSt,dEnd);
		return false;
	}

	double dStValue ,dEndValue,dAssoStValue ,dAssoEndValue;
	GetWireDisObjVoltage(pWireDisObj,dStValue,dEndValue);
	CWireDisplayObj* pAssoWireDis = (CWireDisplayObj*)pAssoWire->GetDisplayObjByLayerIDAndHidedLayer(abs(pWireDisObj->GetLayerId()));
	if (pAssoWireDis == NULL)
	{
		GetWireDisObjVoltage(pWireDisObj,dSt,dEnd);
		return false;
	}
	GetWireDisObjVoltage(pAssoWireDis,dAssoStValue,dAssoEndValue);

	if (pWire->GetStartPin()!= pPin1 && pWire->GetEndPin()!= pPin1)  //pPin1不属于导线;
	{
		if (pWire->GetEndPin() == pPin2)
		{
			dSt = dEndValue;
			if (pAssoWire->GetStartPin() == pPin1)
			{
				dEnd = dAssoStValue;
			}
			else if (pAssoWire->GetEndPin() == pPin1)
			{
				dEnd = dAssoEndValue;
			}
		}
		else if (pWire->GetStartPin() == pPin2)
		{
			dSt = dStValue;
			if (pAssoWire->GetStartPin() == pPin1)
			{
				dEnd = dAssoStValue;
			}
			else if (pAssoWire->GetEndPin() == pPin1)
			{
				dEnd = dAssoEndValue;
			}
		}
	}
	else
	{
		if (pWire->GetStartPin() == pPin1)
		{
			dSt = dStValue;
			if (pAssoWire->GetStartPin() == pPin2)
			{
				dEnd = dAssoStValue;
			}
			else if (pAssoWire->GetEndPin() == pPin2)
			{
				dEnd = dAssoEndValue;
			}
		}
		else if (pWire->GetEndPin() == pPin1)
		{
			dSt = dEndValue;
			if (pAssoWire->GetStartPin() == pPin2)
			{
				dEnd = dAssoStValue;
			}
			else if (pAssoWire->GetEndPin() == pPin2)
			{
				dEnd = dAssoEndValue;
			}
		}
	}

	return true;
}

bool CBigDrawing2MoAnimation::GetWireDisObjCurrent_BelongProxyDeviceOrSepConn(CWireDisplayObj* pWireDisObj,double &dSt,double &dEnd,bool &bConfigPinSt)
{
	dSt=dEnd=0;
	CWire* pWire = (CWire*)pWireDisObj->GetEntityObj();
	CPin* pPin1 = NULL;
	CPin* pPin2 = NULL;
	CWire* pAssoWire = NULL ;
	if ( !m_linkWireTool.GetAssoLinkWire(pWire,pAssoWire,pPin1,pPin2) || pAssoWire == NULL)
	{
		GetWireDisObjCurrent(pWireDisObj,dSt,dEnd); //按照正常的导线获取;
		return false;
	}

	double dStValue ,dEndValue,dAssoStValue ,dAssoEndValue;
	GetWireDisObjCurrent(pWireDisObj,dStValue,dEndValue);
	CWireDisplayObj* pAssoWireDis = (CWireDisplayObj*)pAssoWire->GetDisplayObjByLayerIDAndHidedLayer(abs(pWireDisObj->GetLayerId()));
	if (pAssoWireDis == NULL)
	{
		GetWireDisObjCurrent(pWireDisObj,dSt,dEnd); //按照正常的导线获取;
		return false;
	}
	GetWireDisObjCurrent(pAssoWireDis,dAssoStValue,dAssoEndValue);

	if (pWire->GetStartPin()!= pPin1 && pWire->GetEndPin()!= pPin1)  //pPin1不属于导线;
	{
		if (pWire->GetEndPin() == pPin2)
		{
			bConfigPinSt = false;
			dSt = dEndValue;
			if (pAssoWire->GetStartPin() == pPin1)
			{
				dEnd = dAssoStValue;
			}
			else if (pAssoWire->GetEndPin() == pPin1)
			{
				dEnd = dAssoEndValue;
			}
		}
		else if (pWire->GetStartPin() == pPin2)
		{
			bConfigPinSt = true;
			dSt = dStValue;
			if (pAssoWire->GetStartPin() == pPin1)
			{
				dEnd = dAssoStValue;
			}
			else if (pAssoWire->GetEndPin() == pPin1)
			{
				dEnd = dAssoEndValue;
			}
		}
	}
	else
	{
		if (pWire->GetStartPin() == pPin1)
		{
			bConfigPinSt = true;
			dSt = dStValue;
			if (pAssoWire->GetStartPin() == pPin2)
			{
				dEnd = dAssoStValue;
			}
			else if (pAssoWire->GetEndPin() == pPin2)
			{
				dEnd = dAssoEndValue;
			}
		}
		else if (pWire->GetEndPin() == pPin1)
		{
			bConfigPinSt = false;
			dSt = dEndValue;
			if (pAssoWire->GetStartPin() == pPin2)
			{
				dEnd = dAssoStValue;
			}
			else if (pAssoWire->GetEndPin() == pPin2)
			{
				dEnd = dAssoEndValue;
			}
		}
	}

	return true;
}

//sParamsDataֵΪname,type,value,name,type,value,....;
void CBigDrawing2MoAnimation:: UpdatePowerFlowMoParamsValue(HBaseView* pHView,CString sParamsData/*,int nPositive*/)
{
	m_mapVarValue.clear();
	
	CLayer* pLayer = GetAnimationFlowLayer(pHView);
	if ( !pLayer )
	{
		return;
	}

	CXmlRWUtils::GetStringDataFromStringBySeparator(StringUtils::WStringToString(sParamsData.GetString()), " ", m_mapVarValue);
	
	bool bHasStopAno = false;

	HModelLayerModel* pHmodel = (HModelLayerModel*)pHView->GetModel();
	CSystem* pBigDrawing = pHmodel->GetBigDrawing();
	HBhvBehaviorManager* pBehaviorManager = pHmodel->GetBhvBehaviorManager();
	
	if (m_bShowPowerFlow)
	{
		list<CWireDisplayObj*>::iterator iter_wireDis = m_lstPositiveWireDis.begin(); 
		for ( ; iter_wireDis!= m_lstPositiveWireDis.end(); iter_wireDis++)
		{
			CWireDisplayObj* pWireDis = *iter_wireDis;
			CWire* pWire = (CWire*)pWireDis->GetEntityObj();
			double dStValue ,dEndValue,dSV,dEV;
			ePowerTrackerShowType eType = POWER_TRACKER_HIDE;
			if (m_linkWireTool.IsNeedFindLinkWire(pWire))
			{
				bool bConfigPinSt = false;
				bool bRet1 = GetWireDisObjCurrent_BelongProxyDeviceOrSepConn(pWireDis,dStValue,dEndValue,bConfigPinSt);
				GetWireDisObjVoltage_BelongProxyDeviceOrSepConn(pWireDis,dSV,dEV);
				if (bRet1)
				{
					eType =  GetDirection_BelongProxyDeviceOrSepConn(dStValue,bConfigPinSt);
				}
				else
				{
					eType = GetDirection(dStValue,dEndValue);
				}
			}
			else
			{
				GetWireDisObjCurrent(pWireDis,dStValue,dEndValue);
				GetWireDisObjVoltage(pWireDis,dSV,dEV);
				eType = GetDirection(dStValue,dEndValue);
			}
			ResetSchConAndWireText(pWireDis,dSV,dEV);

			//当前后两次的值发生变化时，反转流动方向;
			if ((pWireDis->GetTrackerStatus()!=POWER_TRACKER_POSITIVE && eType == POWER_TRACKER_POSITIVE)||
				(pWireDis->GetTrackerStatus()!=POWER_TRACKER_NEGATIVE && eType == POWER_TRACKER_NEGATIVE))
			{
				if ( eType == POWER_TRACKER_POSITIVE )
				{
					if(!bHasStopAno)
					{
						bHasStopAno=true;
						pBehaviorManager->Stop();
					}
					if(pWire->IsReverse())
					{
						//设置箭头方向;
						std::list<CTriangleDisplayObj*> triList = pWireDis->GetTriangleList();  
						std::list<CTriangleDisplayObj*>::iterator it_tri = triList.begin();
						for ( ;it_tri!=triList.end();it_tri++)
						{
							CTriangleDisplayObj* pTriangle = *it_tri;
							pTriangle->SetReverseDirection();
						}

						DeleteWireTrackerAnimation(pWireDis, pHView);
						HideOrShowSchWireAssoDisObj(pWireDis,pHView,true);
						CreateWireTrackerAnimation(pWireDis,pHView,true);
						pWire->SetReverse(false);
					}
					else
					{
						DeleteWireTrackerAnimation(pWireDis, pHView);
						HideOrShowSchWireAssoDisObj(pWireDis,pHView,true);
						CreateWireTrackerAnimation(pWireDis,pHView,false);
					}

					pWireDis->SetTrackerStatus(POWER_TRACKER_POSITIVE);
				}
				else if ( eType == POWER_TRACKER_NEGATIVE )
				{
					if(!bHasStopAno)
					{
						bHasStopAno=true;
						pBehaviorManager->Stop();
					}
					if(pWire->IsReverse() == false)
					{
						//设置箭头方向;
						std::list<CTriangleDisplayObj*> triList = pWireDis->GetTriangleList();  
						std::list<CTriangleDisplayObj*>::iterator it_tri = triList.begin();
						for ( ;it_tri!=triList.end();it_tri++)
						{
							CTriangleDisplayObj* pTriangle = *it_tri;
							pTriangle->SetReverseDirection();
						}
						DeleteWireTrackerAnimation(pWireDis, pHView);
						HideOrShowSchWireAssoDisObj(pWireDis,pHView,true);
						CreateWireTrackerAnimation(pWireDis,pHView,true);
						pWire->SetReverse(true);
					}
					else
					{
						DeleteWireTrackerAnimation(pWireDis, pHView);
						HideOrShowSchWireAssoDisObj(pWireDis,pHView,true);
						CreateWireTrackerAnimation(pWireDis,pHView,false);
					}
					pWireDis->SetTrackerStatus(POWER_TRACKER_NEGATIVE);
				}

			}
			else if( eType == POWER_TRACKER_HIDE )
			{
				if(!bHasStopAno)
				{
					bHasStopAno=true;
					pBehaviorManager->Stop();
				}
				DeleteWireTrackerAnimation(pWireDis,pHView);
				HideOrShowSchWireAssoDisObj(pWireDis,pHView,false);
				pWireDis->SetTrackerStatus(POWER_TRACKER_HIDE);
			}
		}

		//显示总线的功率流动画;
		std::list<CSchematicBus*> lstSchBus = pLayer->GetSchBusList();
		std::list<CSchematicBus*>::iterator it_SchBus = lstSchBus.begin();
		for ( ;it_SchBus!=lstSchBus.end();it_SchBus++)
		{
			CSchematicBus* pSchBus = *it_SchBus;
			CSchematicBusDisplayObj* pSchBusDisObj = (CSchematicBusDisplayObj*)pSchBus->GetDisplayObjByLayerID(pLayer->GetId());
			if (!pSchBusDisObj)
			{
				continue;
			}
			//如果包含的连接线都不含功率流则总线也不显示
			bool bCreateNewAnimation= false;
			bool bAllTrackerHide= true;
			std::list<CSchematicBusEntry*> lstSchBusEntry =	pSchBus->GetSchBusEntryList();	
			std::list<CSchematicBusEntry*>::iterator it_schBusEntry = lstSchBusEntry.begin();
			for ( ;it_schBusEntry!=lstSchBusEntry.end();it_schBusEntry++)
			{
				CSchematicBusEntry* pSchBusEntry = *it_schBusEntry;
				CSchematicBusEntryDisplayObj* pSchBusEntryDis = (CSchematicBusEntryDisplayObj*)pSchBusEntry->GetDisplayObjByLayerID(pLayer->GetId());
				CWireDisplayObj* pWireDis = pLayer->GetRealWireDisObjOfBusEntryDisObj(pSchBusEntryDis);
				if (pWireDis==NULL || pWireDis->GetTrackerStatus() == POWER_TRACKER_HIDE )
				{
					continue;
				}
				bAllTrackerHide =false;
				CWire* pSchWire = (CWire*)pWireDis->GetEntityObj();
				CPin* pStPin =  (CPin*)pSchWire->GetStartPin();
				CPin* pEndPin =  (CPin*)pSchWire->GetEndPin();
				if (pStPin == NULL || pEndPin == NULL)
				{
					continue;
				}
				CDisplayObj* pStPinDis = pStPin->GetDisplayObjByLayerID(pWireDis->GetLayerId());
				CDisplayObj* pEndPinDis = pEndPin->GetDisplayObjByLayerID(pWireDis->GetLayerId());
				if (pStPinDis== NULL || pStPin->GetId() == pSchBus->GetStartPinId() || pStPinDis->IsShowThis() == false) 
				{
					if (pWireDis->GetTrackerStatus() == POWER_TRACKER_POSITIVE && pSchBusDisObj->GetTrackerStatus() != POWER_TRACKER_POSITIVE)
					{
						bCreateNewAnimation = true;
						pSchBusDisObj->SetTrackerStatus(POWER_TRACKER_POSITIVE);
					}
					else if (pWireDis->GetTrackerStatus() == POWER_TRACKER_NEGATIVE && pSchBusDisObj->GetTrackerStatus() != POWER_TRACKER_NEGATIVE)
					{
						bCreateNewAnimation = true;
						pSchBusDisObj->SetTrackerStatus(POWER_TRACKER_NEGATIVE);
					}	
				}
				else if (pEndPinDis== NULL || pEndPin->GetId() == pSchBus->GetStartPinId()  || pEndPinDis->IsShowThis() == false)
				{
					if (pWireDis->GetTrackerStatus() == POWER_TRACKER_POSITIVE && pSchBusDisObj->GetTrackerStatus() != POWER_TRACKER_NEGATIVE)
					{
						bCreateNewAnimation = true;
						pSchBusDisObj->SetTrackerStatus(POWER_TRACKER_NEGATIVE);
					}
					else if (pWireDis->GetTrackerStatus() == POWER_TRACKER_NEGATIVE && pSchBusDisObj->GetTrackerStatus() != POWER_TRACKER_POSITIVE)
					{
						bCreateNewAnimation = true;
						pSchBusDisObj->SetTrackerStatus(POWER_TRACKER_POSITIVE);
					}
				}
				break;
			}

			if (bCreateNewAnimation == false && bAllTrackerHide )
			{
				if(!bHasStopAno)
				{
					bHasStopAno=true;
					pBehaviorManager->Stop();
				}
				DeleteWireTrackerAnimation(pSchBusDisObj,pHView);
				HideOrShowBusWireAssoDisObj(pSchBusDisObj,pHView,false);
				pSchBusDisObj->SetTrackerStatus(POWER_TRACKER_HIDE);
			}
			else if (bCreateNewAnimation)
			{
				if(!bHasStopAno)
				{
					bHasStopAno=true;
					pBehaviorManager->Stop();
				}
				DeleteWireTrackerAnimation(pSchBusDisObj, pHView);
				HideOrShowBusWireAssoDisObj(pSchBusDisObj,pHView,true);
				CreateWireTrackerAnimation(pSchBusDisObj,pHView,pSchBusDisObj->GetTrackerStatus() != POWER_TRACKER_POSITIVE);
			}
		}
	}
	
	SetDeviceSwitchStatus();

	if (bHasStopAno)
	{
		pHView->Update();
		pBehaviorManager->Continue();	
	}
}

//tracker全部创建，但并不创建动画，在更新值的时候再创建;
void CBigDrawing2MoAnimation::DisplayAllSchBusAnimation( HBaseView* pHView )
{
	CLayer* pLayer = GetAnimationFlowLayer(pHView);
	if ( !pLayer )
	{
		return;
	}
	std::list<CSchematicBus*> lstSchBus = pLayer->GetSchBusList();
	std::list<CSchematicBus*>::iterator it_SchBus = lstSchBus.begin();
	for (;it_SchBus!=lstSchBus.end();it_SchBus++)
	{
		CSchematicBus* pSchBus = *it_SchBus;
		CSchematicBusDisplayObj* pSchBusDisObj = (CSchematicBusDisplayObj*)pSchBus->GetDisplayObjByLayerID(pLayer->GetId());
		if (!pSchBusDisObj)
		{
			continue;
		}
		COLORREF clr = RGB(pSchBusDisObj->GetColorR()*255.0,pSchBusDisObj->GetColorG()*255.0,pSchBusDisObj->GetColorB()*255.0);			
		pLayer->AddDisObj2PowerFlowDisMap(pSchBusDisObj,clr);	
		CreateAndHideTrackerForSchBus(pSchBusDisObj,pHView);
	}
}

bool CBigDrawing2MoAnimation::ResetSchConAndWireText( CWireDisplayObj* pWireDisObj,double dStValue,double dEndValue)
{

	list<CTextDisplayObj* > lstText = pWireDisObj->GetElecTextList();
	list<CTextDisplayObj* >::iterator iter_text = lstText.begin();
	for ( ; iter_text != lstText.end() ; iter_text++)
	{
		CTextDisplayObj* pTextDisObj = *iter_text;
		double dVol = abs(dStValue - dEndValue);
		CString szValue = StringUtils::CharToWchar(StringUtils::Double2String(dVol,PrecisionNumber).c_str());
		if( pTextDisObj )
		{
			CString szText = _T("压降: ")+szValue+_T("V");
			pTextDisObj->SetTextString(szText);
		}

	}

	return true;
}

bool CBigDrawing2MoAnimation:: DisplayPowerFlowAnimation( HBaseView* pHView )
{
	if (m_bPostData == false)
	{
		m_linkWireTool.ClearData();
		m_linkWireTool.ReadConfigueFile();

		if (m_bShowPowerFlow)
		{
			ImportConfigData::GetPowerWireRule();
			
			CLayer* pLayer = GetAnimationFlowLayer(pHView);
			if (pLayer == NULL)
			{
				return false;
			}

			HModelLayerModel* pHmodel = (HModelLayerModel*)pHView->GetModel();
			CSystem* pBigDrawing = pHmodel->GetBigDrawing();
			GetPositiveShowedWireDisObj(pBigDrawing,pLayer);

			OutputDynamicComponentInfo(pHView);
		}

		m_bPostData = true;
	}
	
	m_mapVarValue.clear();

	SetPowerFlowParams(_T(""));

	ClearSwitchDeviceVec();
	SaveDeviceAndConnDisObjColor();
	
	CModelObjOption::m_isDisplayPowerFlow = true;
	if (m_bShowPowerFlow)
	{
		return DisplayPowerLayerAnimation(pHView);
	}
	else
	{
		return true; 
	}
}

bool PinCmpById(const CPin* p1,const CPin *p2)
{
	long id1 = p1->GetId();
	long id2 = p2->GetId();
	
	return id1<id2;
}


void CBigDrawing2MoAnimation::GetPositiveShowedWireDisObj(CSystem* pBigDrawing,CLayer* pLayer)
{
	m_lstPositiveWireDis.clear();
	m_mapDev2PositiveWires.clear();

	map<CConnector*,list<CPin*>> mapTempConn2Pins;
	list<CWire*> lstAllWire;
	pBigDrawing->GetAllWires(lstAllWire);
	for (list<CWire*>::iterator it = lstAllWire.begin();it!=lstAllWire.end();it++)
	{
		CWire* pWire = *it;
		CWireDisplayObj* pTempDis = (CWireDisplayObj*)pWire->GetDisplayObjByLayerID(pLayer->GetId());
		if (pTempDis && pTempDis->IsShowThis() && !pTempDis->IsHideByMerge())
		{
			CPin* pStPin = pWire->GetStartPin();
			CPin* pEndPin = pWire->GetEndPin(); 
			CConnector* pStCon = pStPin->GetConnector();
			CConnector* pEndCon = pEndPin->GetConnector();
			if (IsMoMergeLayer())
			{
				if (mapTempConn2Pins.find(pStCon) != mapTempConn2Pins.end())
				{
					mapTempConn2Pins[pStCon].push_back(pStPin);
				}
				else
				{
					list<CPin*> lstTempPin;
					lstTempPin.push_back(pStPin);
					mapTempConn2Pins.insert(make_pair(pStCon,lstTempPin));
				}
				if (mapTempConn2Pins.find(pEndCon) != mapTempConn2Pins.end())
				{
					mapTempConn2Pins[pEndCon].push_back(pEndPin);
				}
				else
				{
					list<CPin*> lstTempPin;
					lstTempPin.push_back(pEndPin);
					mapTempConn2Pins.insert(make_pair(pEndCon,lstTempPin));
				}
			}

			if( IsPowerMainWire(pWire))
			{
				m_lstPositiveWireDis.push_back(pTempDis);	
				CDevice* pStDev = dynamic_cast<CDevice*>(pStCon->GetParentEntity());
				CDevice* pEndDev = dynamic_cast<CDevice*>(pEndCon->GetParentEntity());
				if (pStDev)
				{
					if (m_mapDev2PositiveWires.find(pStDev) == m_mapDev2PositiveWires.end())
					{
						list<CWireDisplayObj*> lstWireDis;
						lstWireDis.push_back(pTempDis);
						m_mapDev2PositiveWires.insert(make_pair(pStDev,lstWireDis));
					}
					else
					{
						//逐根便利，不用再找;
						m_mapDev2PositiveWires[pStDev].push_back(pTempDis);
					}
				}
				if (pEndDev)
				{
					if (m_mapDev2PositiveWires.find(pEndDev) == m_mapDev2PositiveWires.end())
					{
						list<CWireDisplayObj*> lstWireDis;
						lstWireDis.push_back(pTempDis);
						m_mapDev2PositiveWires.insert(make_pair(pEndDev,lstWireDis));
					}
					else
					{
						//逐根便利，不用再找;
						m_mapDev2PositiveWires[pEndDev].push_back(pTempDis);
					}
				}
			}
		}
	}

	map<CConnector*,list<CPin*>>::iterator iter_con = mapTempConn2Pins.begin();
	for (;iter_con!= mapTempConn2Pins.end();iter_con++)
	{
		list<CPin*> lstTempPin = iter_con->second;
		lstTempPin.sort();
		lstTempPin.unique();

		lstTempPin.sort(PinCmpById);
		list<CPin*>::iterator iter_pin = lstTempPin.begin();
		for( int i=1;iter_pin!= lstTempPin.end();iter_pin++,i++ )
		{
			CString sIndex;
			sIndex.Format(_T("%d"),i);	
			m_mapPin2VarID.insert(make_pair(*iter_pin,sIndex));
		}
	}
}

ePowerTrackerShowType CBigDrawing2MoAnimation::GetDirection(double dStCurrent,double dEndCurrent)
{
	if (fabs(dStCurrent) < CurrentError)
	{
		if (fabs(dEndCurrent) < CurrentError)
		{
			return POWER_TRACKER_HIDE;
		}
		else if (dEndCurrent <0 )
		{
			return POWER_TRACKER_NEGATIVE;
		}
		else
		{
			return POWER_TRACKER_POSITIVE;
		}
	}
	else if (dStCurrent <0)
	{
		return POWER_TRACKER_POSITIVE;
	}
	else
	{
		return POWER_TRACKER_NEGATIVE;
	}		
}

ePowerTrackerShowType CBigDrawing2MoAnimation::GetDirection_BelongProxyDeviceOrSepConn(double dStCurrent,bool bConfigPinSt)
{
	if (fabs(dStCurrent) < CurrentError)
	{
		return POWER_TRACKER_HIDE;
	}
	else if (dStCurrent <0)
	{
		if (bConfigPinSt)
		{
			return POWER_TRACKER_POSITIVE;
		}
		else
		{
			return POWER_TRACKER_NEGATIVE;
		}
	}
	else
	{
		if (bConfigPinSt)
		{
			return POWER_TRACKER_NEGATIVE;
		}
		else
		{
			return POWER_TRACKER_POSITIVE;
		}
	}	
}

bool CBigDrawing2MoAnimation::StopPowerFlowAnimation( HBaseView* pHView )
{
	m_mapVarValue.clear();
	return CPowerFlow_MoInterface::StopPowerFlowAnimation(pHView);
}

bool CBigDrawing2MoAnimation::DisplayPowerLayerAnimation( HBaseView* pHView )
{
	HModelLayerModel* pHmodel = (HModelLayerModel*)pHView->GetModel();
	CSystem* pBigDrawing = pHmodel->GetBigDrawing();
	CLayer* pLayer = GetAnimationFlowLayer(pHView);
	if ( !pLayer )
	{
		return false;
	}
	CLayerProperty* pLayerProp=pLayer->GetProperty();
	HBhvBehaviorManager *pBehaviorManager = pHView->GetModel()->GetBhvBehaviorManager();
	if (!pBehaviorManager )
	{
		return false;
	}
	if (pBehaviorManager->IsPlaying()) //停止正在显示的功率流动画;
		pBehaviorManager->Stop();

	if (m_lstPositiveWireDis.empty())
	{
		return false;
	}
	list<CWireDisplayObj* >::iterator iter_wireDis = m_lstPositiveWireDis.begin();
	for ( ;iter_wireDis!=m_lstPositiveWireDis.end();iter_wireDis++)
	{
		CWireDisplayObj* pWireDis = *iter_wireDis;
		CWire* pWire = (CWire*) pWireDis->GetEntityObj();
		bool bHideAnnomation = false;

		ePowerTrackerShowType eType = POWER_TRACKER_HIDE;
		double dStartVol ,dEndVol,dStartCur,dEndCur;
		if (m_linkWireTool.IsNeedFindLinkWire(pWire))
		{
			bool bConfigSt =false;
			bool bRet1 = GetWireDisObjVoltage_BelongProxyDeviceOrSepConn(pWireDis,dStartVol,dEndVol);
			GetWireDisObjCurrent_BelongProxyDeviceOrSepConn(pWireDis,dStartCur,dEndCur,bConfigSt);
			eType = GetDirection_BelongProxyDeviceOrSepConn(dStartCur,bConfigSt);
			if (bRet1)
			{
				eType =  GetDirection_BelongProxyDeviceOrSepConn(dStartCur,bConfigSt);
			}
			else
			{
				eType = GetDirection(dStartCur,dEndCur);
			}
		}
		else
		{
			GetWireDisObjVoltage(pWireDis,dStartVol,dEndVol);
			GetWireDisObjCurrent(pWireDis,dStartCur,dEndCur);
			eType = GetDirection(dStartCur,dEndCur);
		}	
		if (eType == POWER_TRACKER_HIDE)
		{
			bHideAnnomation = true;
		}
		std::list<std::pair<double, double> > MidPtList = pWireDis->GetMidPtList();	
		if ( eType == POWER_TRACKER_NEGATIVE)
		{
			MidPtList.reverse();
			pWire->SetReverse(true);
			pWireDis->SetTrackerStatus(POWER_TRACKER_NEGATIVE);
		}
		else
		{
			pWireDis->SetTrackerStatus(POWER_TRACKER_POSITIVE);
			pWire->SetReverse(false);
		}		
		if (!pLayer->IsContainWireDis(pWireDis))
		{
			COLORREF c = RGB(pWireDis->GetColorR()*255.0,pWireDis->GetColorG()*255.0,pWireDis->GetColorB()*255.0);			
			pLayer->AddTriWireDisObj(pWireDis,c);				
		}			

		double threshold = ((HModelLayerView*)pHView)->GetThreshold();
		double DELTA = pLayerProp->GetDblPowerFlowDisplayInterval();

		std::vector<std::pair<double,double> > pTrackerCoorList;  //保存tracker的list;
		std::list<std::pair<double, double> >::iterator iter_first = MidPtList.begin();
		std::list<std::pair<double, double> >::iterator iter_next=iter_first;
		++iter_next; //下一个;	
		for (int n = 1; iter_next!=MidPtList.end();iter_next++,iter_first++, n++)
		{
			double x0 = iter_first->first;
			double y0 = iter_first->second;
			double x1 = iter_next->first;
			double y1 = iter_next->second;
			eTriangleDirection dirc = NODIRECTION;
			pTrackerCoorList.push_back(std::make_pair(x0,y0));
			if (fabs(x0-x1)<=0.1)
			{
				if (y1-y0 > 2*DELTA)
				{
					for (int i = 1;y0+i*DELTA < y1;i++)
					{
						int x = x0;
						int y = y0 + i*DELTA;
						pTrackerCoorList.push_back(std::make_pair(x,y));
					}
				}
				else if (y0-y1 > 2*DELTA)
				{
					for (int i = 1;y0 -i*DELTA > y1;i++)
					{
						int x = x0;
						int y = y0 - i*DELTA;
						pTrackerCoorList.push_back(std::make_pair(x,y));
					}
				}
			}
			else if (fabs(y0-y1)<=0.1)
			{
				if (x1-x0 > 2*DELTA)
				{
					for (int i = 1;x0+i*DELTA < x1;i++)
					{
						int y = y0;
						int x = x0 + i*DELTA;
						pTrackerCoorList.push_back(std::make_pair(x,y));
					}
				}
				else if (x0-x1 > 2*DELTA)
				{
					for (int i = 1;x0 -i*DELTA > x1;i++)
					{
						int y = y0;
						int x = x0 - i*DELTA;
						pTrackerCoorList.push_back(std::make_pair(x,y));
					}
				}
			}

			if (y1 > y0 && fabs(x0-x1)<=0.1)
				dirc = DIRECTION_UP;
			else if (y1 < y0 && fabs(x0-x1)<=0.1)
				dirc = DIRECTION_DOWN;
			else if (x1 < x0 && fabs(y0-y1)<=0.1)
				dirc = DIRECTION_LEFT;
			else if(x1 > x0 && fabs(y0-y1)<=0.1)
				dirc = DIRECTION_RIGHT;					
			if (dirc != NODIRECTION)
			{
				/*CTriangleDisplayObj* pTri = new CTriangleDisplayObj((x0+x1)/2.0,(y0+y1)/2.0,pWireDis->GetLayerId(),dirc);
				pWireDis->AddTriangle(pTri);	
				pTri->SetParentDisObj(pWireDis);
				pTri->SetLayerId(pWireDis->GetLayerId());
				pTri->SetNumber(n);
				pTri->SetThreshold(threshold);
				pTri->SetColor(pWireDis->GetColorR(),pWireDis->GetColorG(),pWireDis->GetColorB());
				double arrowSize = pLayerProp->GetDblPowerFlowArrowSize();
				if ( !bHideAnnomation)
				{
				if (!(fabs(x0-x1)*threshold<=6*arrowSize && fabs(y0-y1)*threshold<=6*arrowSize))
				{
				pHmodel->DisplayObj(pTri);	
				}
				else
				{
				pTri->SetLayerId(-abs(pTri->GetLayerId()));
				}
				}
				else
				{
				pTri->SetLayerId(-abs(pTri->GetLayerId()));
				}*/
				int nTextCount = 1;
				int nTextDistance= 3*DELTA;
				if (dirc ==  DIRECTION_UP || dirc == DIRECTION_DOWN)
				{
					nTextCount = max(abs(y1-y0)/nTextDistance,1);
				}
				else if (dirc ==  DIRECTION_LEFT || dirc == DIRECTION_RIGHT)
				{
					nTextCount = max(abs(x1-x0)/nTextDistance,1);
				}
				for (int nTemp=0;nTemp!=nTextCount;nTemp++)
				{
					CTextDisplayObj* pText = new CTextDisplayObj(pWireDis);
					pWireDis->AddElecText(pText);
					pText->SetVisible(true);
					pText->SetLayerId(pWireDis->GetLayerId());
					pText->CopyDisplayAttri(pWireDis);
					if (dirc == DIRECTION_LEFT || dirc == DIRECTION_RIGHT)	
					{
						if (dirc ==  DIRECTION_LEFT)
						{
							if (nTextCount ==1)
							{
								pText->SetPosX(0.5*(x0+x1));
							}
							else
							{
								pText->SetPosX(x0-(nTemp+1)*nTextDistance);
							}
						}
						else if (dirc ==  DIRECTION_RIGHT)
						{
							if (nTextCount ==1)
							{
								pText->SetPosX(0.5*(x0+x1));
							}
							else
							{
								pText->SetPosX(x0+(nTemp+1)*nTextDistance);
							}
						}
						pText->SetIsHorizon(true);
						pText->SetPosY(0.5*(y0+y1));
						pText->SetPosY(pText->GetPosY() + 3*pWireDis->GetLineWidth());
					}
					else
					{
						if (dirc ==  DIRECTION_UP)
						{	
							if (nTextCount ==1)
							{
								pText->SetPosY(0.5*(y0+y1));
							}
							else
							{
								pText->SetPosY(y0+(nTemp+1)*nTextDistance);
							}							
						} 
						else if (dirc ==  DIRECTION_DOWN)
						{
							if (nTextCount ==1)
							{
								pText->SetPosY(0.5*(y0+y1));
							}
							else
							{
								pText->SetPosY(y0-(nTemp+1)*nTextDistance);
							}	
						}
						pText->SetIsHorizon(false);
						pText->SetPosX(0.5*(x0+x1));
						pText->SetPosX(pText->GetPosX() - 3*pWireDis->GetLineWidth());
					}
					pText->SetIsShowForCurrent(true);
					pText->SetPath(x1-x0,y1-y0);
					pText->SetTextColor(pWireDis->GetColorR(),pWireDis->GetColorG(),pWireDis->GetColorB());
					double textSize = pLayerProp->GetDblPowerFlowTextSize();
					pText->SetTextSize(textSize);
					double dVoltage = abs(dStartVol - dEndVol);
					CString szValue = StringUtils::CharToWchar(StringUtils::Double2String(dVoltage,PrecisionNumber).c_str());
					CString sText =  _T("压降: ")+szValue+_T("V");
					pText->SetTextString(sText);
					if (fabs(x0-x1)*threshold<=6*textSize && fabs(y0-y1)*threshold<=6*textSize)
						pText->SetVisible(false);
					if ( bHideAnnomation)
					{
						pText->SetVisible(false);
					}
				}	
			}	
			if (*iter_next == MidPtList.back())
			{
				pTrackerCoorList.push_back(std::make_pair(x1,y1));
			}
		}
		if (pTrackerCoorList.empty()) 
			continue;

		for (int number = 1;number < pTrackerCoorList.size()+1;number++)  //添加tracker及其流动动画;
		{	
			double xPos = pTrackerCoorList.at(number-1).first;
			double yPos = pTrackerCoorList.at(number-1).second;
			CTrackerDisplayObj* pTracker = new CTrackerDisplayObj(xPos,yPos,pWireDis->GetLayerId());
			pTracker->SetThreshold(threshold);
			pTracker->SetNumber(number);		
			pTracker->SetHeight(pWireDis->GetLineWidth()+1);
			pTracker->SetWidth(pWireDis->GetLineWidth()+1);
			pTracker->SetColor(pWireDis->GetColorR(),pWireDis->GetColorG(),pWireDis->GetColorB());
			pTracker->SetParentDisObj(pWireDis);
			pTracker->SetLayerId(pWireDis->GetLayerId());
			if ( !bHideAnnomation)
			{
				pHmodel->DisplayObj(pTracker);		
			}
			else
			{
				pTracker->SetLayerId(-abs(pTracker->GetLayerId()));
			}
		}
		if ( !bHideAnnomation)
		{
			CreateWireTrackerAnimation(pWireDis,pHView,false);
		}
		else
		{
			pWireDis->SetTrackerStatus(POWER_TRACKER_HIDE);
		}
		pWireDis->SetIsShowPowerFlow(true);
		pHmodel->DisplayObj(pWireDis);
	}

	//显示总线的功率流动画;
	DisplayAllSchBusAnimation(pHView);

	pBehaviorManager->SetUpdateCamera(true);
	pBehaviorManager->SetContinuousPlay(true);
	pBehaviorManager->SetTicksPerSecond(1);  //设置播放速率;
	if (!pBehaviorManager->IsPlaying())
	{
		pBehaviorManager->Continue();
	}
	pHView->Update();

	return true;
}

void CBigDrawing2MoAnimation::CreateAndHideTrackerForSchBus( CSchematicBusDisplayObj* pSchBusDisObj ,HBaseView* pHView)
{
	CLayer* pLayer = GetAnimationFlowLayer(pHView);
	if ( !pLayer )
	{
		return;
	}
	HModelLayerModel* pHmodel = (HModelLayerModel*)pHView->GetModel();
	CSystem* pSystem=pHmodel->GetBigDrawing();
	HBhvBehaviorManager *pBehaviorManager = pHmodel->GetBhvBehaviorManager();
	CSchematicBus* pSchBus = (CSchematicBus*)pSchBusDisObj->GetEntityObj();
	double threshold = ((HModelLayerView*)pHView)->GetThreshold();
	std::list<std::pair<double, double> > MidPtList = pSchBusDisObj->GetPtList();
	std::list<std::pair<double,double> >::reverse_iterator it_res = MidPtList.rbegin();
	it_res++;
	list<CSchematicBusEntry*> lstBusEntry = pSchBus->GetSchBusEntryList();
	bool isChildBusDis = (lstBusEntry.empty() && !pSchBus->GetChildSchBusIdList().empty());
	double xlast = it_res->first;   //有功率流显示的导线对应的总线入口在总线上的点的坐标，离总线最末端最近
	double ylast = it_res->second;  //初始值为总线倒数第二点
	WireDirection eDire = GetDirectionOfSchBusLastSeg(pSchBusDisObj);
	CLayer* pTempLayer=pSystem->GetLayerByID(pSchBusDisObj->GetLayerId());

	if (isChildBusDis)
	{
		list<CSchematicBus*> lstChildBus = pTempLayer->GetChildSchBusList(pSchBus); 
		for (list<CSchematicBus*>::iterator it_bus = lstChildBus.begin();it_bus!=lstChildBus.end();it_bus++)
		{
			CSchematicBusDisplayObj* pBusDis = (CSchematicBusDisplayObj*)(*it_bus)->GetDisplayObjByLayerID(pSchBusDisObj->GetLayerId());
			pair<double,double> ptFirst = pBusDis->GetPtList().front();
			if (eDire == WD_NORTH)
			{
				if (ylast < ptFirst.second)
				{
					ylast = ptFirst.second;
				}
			}
			else if (eDire == WD_SOUTH)
			{
				if (ylast > ptFirst.second)
				{
					ylast = ptFirst.second;
				}
			}
			else if (eDire == WD_EAST)
			{
				if (xlast < ptFirst.first)
				{
					xlast = ptFirst.first;
				}
			}
			else if (eDire == WD_WEST)
			{
				if (xlast > ptFirst.first)
				{
					xlast = ptFirst.first;
				}
			}
		}
	}
	else
	{
		for (list<CSchematicBusEntry*>::iterator it_entry = lstBusEntry.begin();
			it_entry != lstBusEntry.end();it_entry++)
		{
			CSchematicBusEntryDisplayObj* pEntryDis = (CSchematicBusEntryDisplayObj*)(*it_entry)->GetDisplayObjByLayerID(pSchBusDisObj->GetLayerId());	
			CWireDisplayObj* pWireDis = pLayer->GetRealWireDisObjOfBusEntryDisObj(pEntryDis);
			if (pWireDis)
			{
				HPoint startPoint,endPoint;
				pEntryDis->GetStartAndEndPoint(startPoint,endPoint);
				switch(eDire)
				{
				case WD_NORTH:
					{
						if (ylast < startPoint.y)
						{
							ylast = startPoint.y;
						}
					}
					break;
				case WD_SOUTH:
					{
						if (ylast > startPoint.y)
						{
							ylast = startPoint.y;
						}
					}
					break;
				case WD_EAST:
					{
						if (xlast < startPoint.x)
						{
							xlast = startPoint.x;
						}
					}
					break;
				case WD_WEST:
					{
						if (xlast > startPoint.x)
						{
							xlast = startPoint.x;
						}
					}
				}
			}
		}
	}

	std::list<std::pair<double, double> >::iterator iter_first = MidPtList.begin();
	std::list<std::pair<double, double> >::iterator iter_next=iter_first;
	++iter_next; //下一个;	

	std::vector<std::pair<double,double> > TrackerCoorList;
	CLayerProperty* pLayerProp=pLayer->GetProperty();
	double DELTA = pLayerProp->GetDblPowerFlowDisplayInterval(); 
	for (int n = 1; iter_next!=MidPtList.end();iter_next++,iter_first++, n++)
	{
		double x0 = iter_first->first;
		double y0 = iter_first->second;
		double x1,y1;
		if (*iter_next == MidPtList.back())
		{
			x1 = xlast;
			y1 = ylast;
		}
		else
		{
			x1 = iter_next->first;
			y1 = iter_next->second;
		}

		eTriangleDirection dirc = NODIRECTION;
		TrackerCoorList.push_back(std::make_pair(x0,y0));
		if (fabs(x0-x1)<=0.1)
		{
			if (y1-y0 > 2*DELTA)
			{
				for (int i = 1;y0+i*DELTA < y1;i++)
				{
					int x = x0;
					int y = y0 + i*DELTA;
					TrackerCoorList.push_back(std::make_pair(x,y));
				}
			}
			else if (y0-y1 > 2*DELTA)
			{
				for (int i = 1;y0 -i*DELTA > y1;i++)
				{
					int x = x0;
					int y = y0 - i*DELTA;
					TrackerCoorList.push_back(std::make_pair(x,y));
				}
			}
		}
		else if (fabs(y0-y1)<=0.1)
		{
			if (x1-x0 > 2*DELTA)
			{
				for (int i = 1;x0+i*DELTA < x1;i++)
				{
					int y = y0;
					int x = x0 + i*DELTA;
					TrackerCoorList.push_back(std::make_pair(x,y));
				}
			}
			else if (x0-x1 > 2*DELTA)
			{
				for (int i = 1;x0 -i*DELTA > x1;i++)
				{
					int y = y0;
					int x = x0 - i*DELTA;
					TrackerCoorList.push_back(std::make_pair(x,y));
				}
			}
		}
		if (*iter_next == MidPtList.back())
		{
			TrackerCoorList.push_back(std::make_pair(x1,y1));
		}
	}
	
	for (int number = 1;number < TrackerCoorList.size()+1;number++)
	{	
		double xPos = TrackerCoorList.at(number-1).first;
		double yPos = TrackerCoorList.at(number-1).second;
		CTrackerDisplayObj* pTracker = new CTrackerDisplayObj(xPos,yPos,pSchBusDisObj->GetLayerId());
		pTracker->SetThreshold(threshold);
		pTracker->SetNumber(number);		
		pTracker->SetWidth(pSchBusDisObj->GetLineWidth()+1);
		pTracker->SetHeight(pSchBusDisObj->GetLineWidth()+1);
		pTracker->SetColor(pSchBusDisObj->GetColorR(),pSchBusDisObj->GetColorG(),pSchBusDisObj->GetColorB());
		pTracker->SetParentDisObj(pSchBusDisObj);
		pTracker->SetLayerId(0-abs(pSchBusDisObj->GetLayerId()));
	}
	
	pSchBusDisObj->SetTrackerStatus(POWER_TRACKER_HIDE);
	pSchBusDisObj->SetIsShowPowerFlow(true);
	pHmodel->DisplayObj(pSchBusDisObj);
}

void CBigDrawing2MoAnimation::GetWireDisObjMergerdPins(CWireDisplayObj* pWireDisObj,vector<CPin* > &vecStPins,vector<CPin* > &vecEndPins)
{
	if ( m_mapWire2MergePins.find(pWireDisObj) != m_mapWire2MergePins.end())
	{
		vecStPins = m_mapWire2MergePins[pWireDisObj].first;
		vecEndPins = m_mapWire2MergePins[pWireDisObj].second;
		return;
	}

	CConnector* pStCon = ((CWire*)pWireDisObj->GetEntityObj())->GetStartPin(false)->GetConnector();
	CConnector* pEndCon = ((CWire*)pWireDisObj->GetEntityObj())->GetEndPin(false)->GetConnector();
	list<CEntityObj *> lstEnt = pWireDisObj->GetCombineEntityList();  //包含自身在内的所有实体;
	list<CEntityObj *>::iterator iter= lstEnt.begin();
	for ( ; iter != lstEnt.end(); iter++)
	{
		if ((*iter)->IsWire() ==  false)
		{
			continue;
		}
		CWire* pWire = (CWire*)(*iter);
		CPin* pStPin = pWire->GetStartPin(false);
		CPin* pEndPin = pWire->GetEndPin(false);
		if (pStPin == NULL || pEndPin ==NULL)
		{
			assert(FALSE);
			continue;
		}
		if (pStPin->GetConnector() ==  pStCon)
		{
			vecStPins.push_back(pStPin);
			vecEndPins.push_back(pEndPin);
		}
		else
		{
			vecStPins.push_back(pEndPin);
			vecEndPins.push_back(pStPin);
		}
	}
	if (lstEnt.empty())
	{
		vecStPins.push_back(((CWire*)pWireDisObj->GetEntityObj())->GetStartPin(false));
		vecEndPins.push_back(((CWire*)pWireDisObj->GetEntityObj())->GetEndPin(false));
	}

	m_mapWire2MergePins.insert(make_pair(pWireDisObj,make_pair(vecStPins,vecEndPins)));
}

double CBigDrawing2MoAnimation::GetPinCurrentValue(CPin* pPin)
{
	CString szName = GetPinCurrentVarName(pPin);
	string sName;
	StringUtils::CStringToStdstring(szName,sName);
	map<string,double>:: iterator iter = m_mapVarValue.find(sName);
	if ( iter != m_mapVarValue.end())
	{
		return iter->second;		
	}

	return 0;
}

double CBigDrawing2MoAnimation::GetPinVoltageValue(CPin* pPin)
{
	CString szName = GetPinVoltageVarName(pPin);
	string sName;
	StringUtils::CStringToStdstring(szName,sName);
	map<string,double>:: iterator iter = m_mapVarValue.find(sName);
	if ( iter != m_mapVarValue.end())
	{
		return iter->second;		
	}

	return 0;
}

//电压取第一根的，即管脚名称最小的;
void CBigDrawing2MoAnimation::GetWireDisObjVoltage( CWireDisplayObj* pWireDisObj,double &dSt,double &dEnd)
{
	dSt = dEnd =0;
	if (IsMoMergeLayer())
	{
		CWire* pWire = (CWire*)pWireDisObj->GetEntityObj();
		CPin* pStPin = pWire->GetStartPin();
		CPin* pEndPin = pWire->GetEndPin();
		dSt = GetPinVoltageValue(pStPin);
		dEnd = GetPinVoltageValue(pEndPin);

		return;
	}


	vector<CPin* > vecStPins,vecEndPins;//合并的管脚所代表的管脚集合;
	GetWireDisObjMergerdPins(pWireDisObj,vecStPins,vecEndPins);
	map<int,double> mapStValue,mapEndValue;
	for (int nIndex=0; nIndex!= vecStPins.size() ; nIndex++)
	{
		CPin* pPin = vecStPins[nIndex];
		mapStValue.insert(make_pair(_ttoi(pPin->GetName()),GetPinVoltageValue(pPin)));
	}
	for (int nIndex=0; nIndex!= vecEndPins.size() ; nIndex++)
	{
		CPin* pPin = vecEndPins[nIndex];
		mapEndValue.insert(make_pair(_ttoi(pPin->GetName()),GetPinVoltageValue(pPin)));
	}
	if (mapStValue.empty() == false)
	{
		dSt = mapStValue.begin()->second;
	}
	if (mapEndValue.empty() == false)
	{
		dEnd = mapEndValue.begin()->second;
	}

}

//电流取和;
void CBigDrawing2MoAnimation::GetWireDisObjCurrent( CWireDisplayObj* pWireDisObj,double &dSt,double &dEnd)
{
	dSt = dEnd =0;
	if (IsMoMergeLayer())
	{
		CWire* pWire = (CWire*)pWireDisObj->GetEntityObj();
		CPin* pStPin = pWire->GetStartPin();
		CPin* pEndPin = pWire->GetEndPin();
		dSt = GetPinCurrentValue(pStPin);
		dEnd = GetPinCurrentValue(pEndPin);

		return;
	}


	vector<CPin* > vecStPins,vecEndPins;//合并的管脚所代表的管脚集合;
	GetWireDisObjMergerdPins(pWireDisObj,vecStPins,vecEndPins);
	for (int nIndex=0; nIndex!= vecStPins.size() ; nIndex++)
	{
		CPin* pPin = vecStPins[nIndex];
		dSt += GetPinCurrentValue(pPin);
	}
	for (int nIndex=0; nIndex!= vecEndPins.size() ; nIndex++)
	{
		CPin* pPin = vecEndPins[nIndex];
		dEnd += GetPinCurrentValue(pPin);
	}
}

CString CBigDrawing2MoAnimation::GetPinCurrentVarName( CPin* pPin )
{
	CString sRet;
	CConnector* pCon = pPin->GetConnector();
	CEntityObj* pEnt = pCon->GetParentEntity();
	if (pEnt->IsDevice())
	{
		CString sDevCode = ((CDevice*)pEnt)->GetNo();
		CString strDevPre = sDevCode;
		CString sConCode = pCon->GetCode();
		int nPos = sConCode.Find(strDevPre);
		if (nPos != -1)
		{
			sConCode = sConCode.Right(sConCode.GetLength() - (nPos+sDevCode.GetLength()+1)); //减去设备代号及“-”;
		}
		else
		{
			//排除接插件代号为 EP-O,EP-f 情况;
			if( sConCode.Find(',') < 0 && sConCode.Find('，') <0)
			{
				nPos = sConCode.Find('-');
				if (nPos >=0)
				{
					sConCode = sConCode.Right(sConCode.GetLength()-nPos-1);
				}
			}
		}

		CString sPinName = pPin->GetName();
		if (IsMoMergeLayer() && m_mapPin2VarID.find(pPin) != m_mapPin2VarID.end())
		{
			sPinName = m_mapPin2VarID[pPin];
		}

		sRet = sDevCode+_T(".")+sConCode+_T("[")+sPinName+_T("].i");
		sRet.Replace(_T("-"),_T("_"));
		sRet.Replace(_T(","),_T("_"));
		sRet.Replace(_T("，"),_T("_"));
		sRet.Replace(_T(" "),_T(""));
	}
	else if(pCon->IsSeparateConnector())
	{
		CString sLeftCon,sRightCon;
		CString sConCode = pCon->GetCode();
		int nPos = sConCode.ReverseFind('-');
		if (nPos != -1)
		{
			sLeftCon = sConCode.Left(nPos);
			sRightCon = sConCode.Right(sConCode.GetLength()-nPos-1);
		}

		CString sPinName = pPin->GetName();
		if (IsMoMergeLayer() && m_mapPin2VarID.find(pPin) != m_mapPin2VarID.end())
		{
			sPinName = m_mapPin2VarID[pPin];
		}

		sRet =sLeftCon+ _T(".")+sRightCon+_T("[")+sPinName+_T("].i");
		sRet.Replace(_T("-"),_T("_"));
		sRet.Replace(_T(","),_T("_"));
		sRet.Replace(_T("，"),_T("_"));
		sRet.Replace(_T(" "),_T(""));

	}
	return sRet;
}

CString CBigDrawing2MoAnimation::GetPinVoltageVarName( CPin* pPin )
{
	CString sRet;
	CConnector* pCon = pPin->GetConnector();
	CEntityObj* pEnt = pCon->GetParentEntity();
	if (pEnt->IsDevice())
	{
		CString sDevCode = ((CDevice*)pEnt)->GetNo();
		CString strDevPre = sDevCode;
		CString sConCode = pCon->GetCode();
		int nPos = sConCode.Find(strDevPre);
		if (nPos != -1)
		{
			sConCode = sConCode.Right(sConCode.GetLength() - (nPos+sDevCode.GetLength()+1)); //减去设备代号及“-”
		}
		else
		{
			//排除接插件代号为 EP-O,EP-f 情况;
			if( sConCode.Find(',') < 0 && sConCode.Find('，') <0)
			{
				nPos = sConCode.Find('-');
				if (nPos >=0)
				{
					sConCode = sConCode.Right(sConCode.GetLength()-nPos-1);
				}
			}
		}

		CString sPinName = pPin->GetName();
		if (IsMoMergeLayer() && m_mapPin2VarID.find(pPin) != m_mapPin2VarID.end())
		{
			sPinName = m_mapPin2VarID[pPin];
		}

		sRet = sDevCode+_T(".")+sConCode+_T("[")+sPinName+_T("].v");
		sRet.Replace(_T("-"),_T("_"));
		sRet.Replace(_T(","),_T("_"));
		sRet.Replace(_T("，"),_T("_"));
		sRet.Replace(_T(" "),_T(""));
	}
	else if(pCon->IsSeparateConnector())
	{
		CString sLeftCon,sRightCon;
		CString sConCode = pCon->GetCode();
		int nPos = sConCode.ReverseFind('-');
		if (nPos != -1)
		{
			sLeftCon = sConCode.Left(nPos);
			sRightCon = sConCode.Right(sConCode.GetLength()-nPos-1);
		}

		CString sPinName = pPin->GetName();
		if (IsMoMergeLayer() && m_mapPin2VarID.find(pPin) != m_mapPin2VarID.end())
		{
			sPinName = m_mapPin2VarID[pPin];
		}

		sRet =sLeftCon+ _T(".")+sRightCon+_T("[")+sPinName+_T("].v");
		sRet.Replace(_T("-"),_T("_"));
		sRet.Replace(_T(","),_T("_"));
		sRet.Replace(_T("，"),_T("_"));
		sRet.Replace(_T(" "),_T(""));

	}
	return sRet;
}

bool CBigDrawing2MoAnimation::IsPowerReturnWire(CWire* pWire)
{
	return pWire->IsPowerReturnWire();
}

bool CBigDrawing2MoAnimation::IsPowerMainWire(CWire* pWire)
{
	return pWire->IsPowerMainWire();
}
//根据功耗来判读;
bool CBigDrawing2MoAnimation::IsDeviceCloseSwitch(HBaseView* pHView,CDeviceDisplayObj* pDevDis)
{
	CDevice* pDev = (CDevice*)pDevDis->GetEntityObj();

	CSubSystem *pSubSys = (CSubSystem*)pDev->GetParentEntity();
	if( pSubSys==NULL )
		return true;

	if( IsPowerSupplySystem(pSubSys) )
		return false;

	CString sDevPower = GetDevicePowerLossVarName(pDev);
	string sPower;
	StringUtils::CStringToStdstring(sDevPower,sPower);
	if ( m_mapVarValue.find(sPower) == m_mapVarValue.end() ) //找不到则关机;
	{
		return true;
	}

	return m_mapVarValue[sPower]<0.01;

	//CLayer* pLayer = GetAnimationFlowLayer(pHView);
	//if ( !pLayer )
	//{
	//	return false;
	//}

	//bool bDevNotClose = false;
	//CDevice* pDev = (CDevice*)pDevDis->GetEntityObj();
	//if (m_mapDev2PositiveWires.find(pDev) == m_mapDev2PositiveWires.end())
	//{
	//	return true;
	//}

	//list<CWireDisplayObj*> lstWireDis = m_mapDev2PositiveWires[pDev];
	//list<CWireDisplayObj*>::iterator iter_wireDis = lstWireDis.begin();
	//for (; iter_wireDis!= lstWireDis.end(); iter_wireDis++)
	//{
	//	CWireDisplayObj* pWireDis=  *iter_wireDis;
	//	if (pWireDis->GetTrackerStatus() != POWER_TRACKER_HIDE)
	//	{
	//		bDevNotClose = true;
	//		break;
	//	}
	//}

	//if ( !bDevNotClose )
	//{
	//	return true;
	//}

	//return false;
}

CLayer* CBigDrawing2MoAnimation::GetAnimationFlowLayer( HBaseView* pHView )
{
	//CSystem* pBigDrawing = CModelObjOption::GetIModelObjEventHandler()->GetActiveSystem();
	HModelLayerModel* pHmodel = (HModelLayerModel*)pHView->GetModel();
	CSystem* pBigDrawing = pHmodel->GetBigDrawing();

	list<CLayer*> lstLayer = pBigDrawing->GetLayerList();
	for (list<CLayer*>::iterator iter= lstLayer.begin();iter!= lstLayer.end();iter++)
	{
		CLayer* pLayer = *iter;
		if (pLayer->GetLayerLevelType() == POWER_FLOW_LAYER && pLayer->GetName().Find(_T("功率")) !=-1 )
		{
			return pLayer;
		}
	}

	return NULL;
}
